
//------------------------------------------------------------------------------
pulse.server.ServerResponse = function( bExecuted, sData )
{
	this.bExecuted 	= bExecuted;
	this.sData 		= sData;
}

//------------------------------------------------------------------------------
pulse.server._parseErrorXMLNode = function( oNode )
{
	pulse.error( pulse.xml.getText( oNode ) );
}

//------------------------------------------------------------------------------
pulse.server._parseWarningXMLNode = function( oNode )
{
	pulse.warning( pulse.xml.getText( oNode ) );
}

//------------------------------------------------------------------------------
pulse.server._parseInfoXMLNode = function( oNode )
{
	pulse.info( pulse.xml.getText( oNode ) );
}

//------------------------------------------------------------------------------
pulse.server._parseDebugXMLNode = function( oNode )
{
	pulse.debug( pulse.xml.getText( oNode ) );
}

//------------------------------------------------------------------------------
pulse.server._parseDataXMLNode = function( oNode )
{
	return oNode.getFirstChild().getNodeValue();
}

//------------------------------------------------------------------------------
/**
 * Sends a request to the server and uses the callback data to process the asynchronous response
 * For example you can call it this way :
 * 
 * function onSuccess( oResp )
 * {
 * 	alert ( oResp.serverResponse.sData );
 *  alert ( oResp.argument.name + " : " + oResp.argument.size );
 * }
 * ...
 * var oCallbackData = 
 * {
 * 	success : onSuccess,
 *  failure : SOME_OTHER_FUNCTION,
 *  argument : { name : 'chicken', height : '11' }
 * }
 * pulse.server.sendRequest( "php/content.php?command=load_file&file=test/chicken.char.xml", oCallbackData );
 *  
 * @param {} sUrl the server file to call with its parameters (GET method)
 * @param {} oCallbackData a structure containing : success (callback), failure (callback), argument (a structure of what you want inside), scope
 */
pulse.server.sendRequest = function( sUrl, oCallbackData )
{
	var createCompleteCallback = function( cb )
	{
         return function( xhr, status )
         {
         	// error without any response
            if( ( status == 'error' || status == 'timeout' ) && cb.failure )
            {
            	if ( status == 'error' )
            		pulse.error( 'cannot send request to server' );
            	else if ( status == 'timeout' )
            		pulse.error( 'cannot send request to server : timeout' );
                cb.failure.call
                (
                	cb.scope||window, 
                	{
	                    serverResponse: new this.ServerResponse( false, '' ),
	                    argument: cb.argument
                	}
                );
            }
            // process server response
            else
            {
            	//alert( xhr.responseText );
            	var oResp = pulse.server.parseResponse( xhr.responseText );
            	
            	// if request executed (can contains errors however, but the main request goal is a success)
            	if ( oResp.bExecuted )
            	{
            		if ( cb.success )
		                cb.success.call
		                (
		                	cb.scope||window, 
		                	{
		                    	serverResponse: oResp,
		                    	argument: cb.argument
		               		}
		               	);
            	}
            	// if the request was not executed
	            else if ( cb.failure )
	            {
	            	cb.failure.call
	                (
	                	cb.scope||window, 
	                	{
	                    	serverResponse: oResp,
	                    	argument: cb.argument
	               		}
	               	);
	            }
            }
         };
    };
	var oRequest = 
	{
		type : "GET",
		url : sUrl,
		data : null,
		timeout : 30 * 1000,
		complete : createCompleteCallback( oCallbackData )
	}
	jQuery.ajax( oRequest );
}

//------------------------------------------------------------------------------
pulse.server.getCommandUrl = function( sCommand, sArgs, oCallbackData )
{
	return 'php/content.php?command=' + sCommand + '&' + sArgs;
}

//------------------------------------------------------------------------------
pulse.server._lastServerResponseXMLData = null;

//------------------------------------------------------------------------------
/** 
 * \param sXmlData a string containing the XML server response to parse
 * \return a pulse.server.ServerResponse object containing data and other useful information */
pulse.server.parseResponse = function( sXmlData )
{
	//alert ( sXmlData );
	pulse.server._lastServerResponseXMLData = sXmlData;
	
	var bRequestExecuted = false;
	try
	{
		var oDom 	= pulse.xml.domParser.loadXML( sXmlData );
	} catch( e )
	{
		pulse.error( 'Cannot xml-parse the server response' );
		pulse.exception( e );
		return new this.ServerResponse( false, '' );
	}
	
	try
	{
		var oRoot 	= oDom.getDocumentElement();
		
		if ( oRoot == null )
		{
			pulse.error( 'Cannot get the root element of the server response' );
			return new this.ServerResponse( false, '' );
		}
		
		if ( oRoot.getTagName() != 'server-response' )
		{
			pulse.error( 'the server response does not contain the main element "server-response"' );
			return new this.ServerResponse( false, '' );
		}
		
		var oChild = oRoot.getFirstChild();
		
		var sData = "";
		
		while ( oChild != null )
		{
			if ( oChild.getNodeType() == 1 )
			{
				switch ( oChild.getTagName() )
				{
					case 'error' : 		this._parseErrorXMLNode( oChild ); break;
					case 'warning' :	this._parseWarningXMLNode( oChild ); break;
					case 'info' : 		this._parseInfoXMLNode( oChild ); break;
					case 'debug' : 		this._parseDebugXMLNode( oChild ); break;
					case 'data' : 		sData += this._parseDataXMLNode( oChild ); break;
					case 'executed' :	bRequestExecuted = true; break;
					default : 			pulse.warning( 'Element "' + oChild.getNodeName() + '" not recognized in the XLM server response.'); break;
				}
			}
			
			oChild = oChild.getNextSibling();
		}
	} catch ( e )
	{
		pulse.exception( e );
	}

	return new this.ServerResponse( bRequestExecuted, sData );
}